perm filename CS106[1,RWF] blob sn#486254 filedate 1979-10-25 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00005 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	Symmetry in Programming.
C00004 00003
C00006 00004	Here, we could print the first four lines, counting from zero (important!) by
C00009 00005	where the fourth through the ninth lines are taken as the repeating unit,
C00011 ENDMK
CāŠ—;
Symmetry in Programming.

When you were a child, you probably were shown how to cut out a figure of a
heart:





by folding a piece of paper in half and cutting half a heart:







By using the symmetry of the figure, you reduced your work by half.  
Furthermore, the method guaranteed that, even if your cutting was imperfect,
the result would be perfectly symmetrical.

The same method works in computer programs.  If you are designing an
iteration using an iteration variable, and if the action to be carried out
is the same for corresponding positive and negative values of the
iteration variable, you can take the absolute value of the iteration
variable and work on that, dealing only with the positive half of the
iteration.  The negative half automatically works out.













To draw this figure, plan the iteration this way:
	FOR LINE := -10 TO 10 DO
		BEGIN
		ABSLINE := ABS(LINE)
		Print the asterisks for line number ABSLINE
		WRITELN
		END	
and then elaborate the ``Print the asterisks'' part into:
	FOR COLUMN := 1 TO 10 + ABSLINE DO
		WRITE(`*')
The program is designed to print the lower half of the figure; the upper half
comes along automatically.











Similarly to print the above number  3 , we set up the framework
	FOR LINE := -10 TO 10 DO
		BEGIN
		ABSLINE := ABS(LINE)
		Print enough spces;
		WRITELN(`*')
		END	
and then design the elaboration of ``Print enough spaces'' to print the
spaces of the lower circle:
		WIDTH := SQRT(36-SQR(ABSLINE-6))
		FOR COLUMN := 1 TO ROUND(WIDTH)-1 DO
			WRITE(`b')

Such a symmetry does not need to be visual; to identify an integer
input as a one, two, or three-digit number, the same symmetry method 
simplifies the decision:
	READ(NUMBER)
	ABSNUM := ABS(NUMBER);
	IF ABSNUM < 10 THEN
		WRITELN(`ONE DIGIT')
	ELSE IF ABSNUM < 100 THEN
		WRITELN(`TWO DIGITS)
	ELSE WRITELN(`THREE OR MORE DIGITS')
The above symmetries are mirror symmetries.  Another type is periodic symmetry,
in which the same behavior occurs repeatedly:

	X
	XX
	XXX
	XXXX
	X
	XX
	XXX
	XXXX
	X
	XX
	XXX
	XXXX

Here, we could print the first four lines, counting from zero (important!) by
	FOR LINE := 0 TO 3 DO
		BEGIN
		FOR COLUMN := 1 TO LINE+1 DO
			WRITE(`*');
		WRITELN
		END
If LINE reaches  4 , however, we want to do the same thing as at  0 ,  5  is
the same as  1 , etc.  If we divide LINE by  4  and take the remainder, we
are in effect subtracting away  4  as many times as possible, and we are
left with the corresponding number among lines  0  through  3 .  We already
know what to do with those lines, so the program is
	FOR LINE := 0 TO 11 DO
		BEGIN
		LINE03 := LINE MOD 4;
		FOR COLUMN := 1 TO LINE03 +1 DO
			WRITE(`*');
		WRITELN
		END	
Again, the symmetry need not be visual.  To print the values of variables
X , Y , and  Z  every tenth time through a certain iteration, we might write
	FOR COUNT := 0 TO ... DO
		BEGIN
		IF COUNT MOD 10 = 9 THEN
			BEGIN
			WRITELN;
			WRITELN(`X',X,`Y',Y,`Z',Z)
			END;
		Rest of the computation
		END
This method of handling periodic behavior can easily be adapted to start a
new line, or a new page, whenever a specified number of outputs is printed.
By combining the two methods for mirror symmetry and periodicity, we make
it easy to print this figure:

	X
	XXX
	XXXXX
	XXXXX
	XXX
	X
	X
	XXX
	XXXXX
	XXXXX
	XXX
	X

where the fourth through the ninth lines are taken as the repeating unit,
because the mirror symmetry is very easy to handle that way.
	FOR LINE := 3 TO ... DO
		BEGIN
		LINE05 := LINE MOD 6;
		LINE135 := ABS(2*LINE05-5);
		FOR COL := 1 TO LINE135 DO
			WRITE(`*');
		WRITELN
		END
 
Exercise.   This program fragment is intended to do action  A  before every
fifth performance of action  B .  Find both bugs and correct them.
	FOR ... DO
	BEGIN
	...
	...
	COUNT := 1;
	IF COUNT = 5 THEN
		BEGIN
		A;
		COUNT := 1
		END;
	B;
	COUNT := COUNT+1
	...
	...
	END